using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO;

namespace Kyoh.Lib.WinForms
{
	public class FolderTreeView : TreeView
	{
		private ImageList _folderTreeViewImageList;
		private readonly System.Globalization.CultureInfo _cultureInfo = System.Globalization.CultureInfo.CurrentCulture;

		#region Constructors

		public FolderTreeView()
		{
			BeforeExpand += TreeViewBeforeExpand;
		}

		public void InitFolderTreeView()
		{
			InitImageList();
			ShellOperations.PopulateTree(this, ImageList);
			if(Nodes.Count > 0)
			{
                if (InvokeRequired)
                    Invoke(new Action<bool>(b => Nodes[0].Expand()), false);
                else
                    Nodes[0].Expand();
			}
		}

		private void InitImageList()
		{
			// setup the image list to hold the folder icons
		    _folderTreeViewImageList = new ImageList
		                                   {
		                                       ColorDepth = ColorDepth.Depth32Bit,
		                                       ImageSize = new Size(16, 16),
		                                       TransparentColor = Color.Transparent
		                                   };

		    // add the Desktop icon to the image list
			try
			{
				_folderTreeViewImageList.Images.Add(ExtractIcons.GetDesktopIcon());
			}
			catch
			{
				// Create a blank icon if the desktop icon fails for some reason
				var bmp = new Bitmap(16,16);
				var img = (Image)bmp;
				_folderTreeViewImageList.Images.Add((Image)img.Clone());
				bmp.Dispose();
			}
            if (InvokeRequired)
                Invoke(new Action<bool>(b => SetImageList()), false);
            else
                SetImageList();
		}

	    private void SetImageList()
        {
            ImageList = _folderTreeViewImageList;
        }

	    #endregion

		#region Event Handlers

		private void TreeViewBeforeExpand(object sender, TreeViewCancelEventArgs e)
		{
			BeginUpdate();
			ShellOperations.ExpandBranch(e.Node, ImageList);
			EndUpdate();
		}

		#endregion

		#region Kyoh.Lib.WinForms.FolderTreeView Properties & Methods

		public string GetSelectedNodePath()
		{
			return ShellOperations.GetFilePath(SelectedNode);
		}

		public bool DrillToFolder(string folderPath)
		{
			bool folderFound = false;
			if(Directory.Exists(folderPath)) // don't bother drilling unless the directory exists
			{
				BeginUpdate();
				// if there's a trailing \ on the folderPath, remove it unless it's a drive letter
				if(folderPath.Length > 3 && folderPath.LastIndexOf("\\", System.StringComparison.Ordinal) == folderPath.Length -1)
					folderPath = folderPath.Substring(0, folderPath.Length -1);
				//Start drilling the tree
				DrillTree(Nodes[0].Nodes, folderPath.ToUpper(_cultureInfo), ref folderFound);
				EndUpdate();
			}
			if(!folderFound)
				SelectedNode = Nodes[0];
			return folderFound;
		}

		private void DrillTree(TreeNodeCollection tnc, string path, ref bool folderFound)
		{
			foreach(TreeNode tn in tnc)
			{
				if(!folderFound)
				{
					SelectedNode = tn;
					var tnPath = ShellOperations.GetFilePath(tn).ToUpper(_cultureInfo);
					if(path == tnPath && !folderFound)
					{
						SelectedNode = tn;
						tn.EnsureVisible();
						folderFound = true;
						break;
					}
				    if(path.IndexOf(tnPath, System.StringComparison.Ordinal) > -1 && !folderFound)
				    {
				        tn.Expand();
				        DrillTree(tn.Nodes, path, ref folderFound);
				    }
				}
			}
		}


		#endregion
    }
}

